package com.hty.locusmap;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.os.Environment;
import android.util.Log;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.CoordinateConverter;
import com.baidu.mapapi.utils.CoordinateConverter.CoordType;
import com.baidu.mapapi.utils.DistanceUtil;

public class RWXML {
	static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
	static SimpleDateFormat SDF_HMS = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
	static int seconds, h, m, s;
	static DecimalFormat DF = new DecimalFormat("0.0");

	static void create(String time) {
		String fp = Environment.getExternalStorageDirectory().getPath() + "/LocusMap/";
		//String fn = time + "BD.gpx";
		String fn = time + ".gpx";
		String fpn = fp + fn;
		MainApplication.wfp = fpn;
		// Log.e("xmlFile", fpn);
		File filepath = new File(fp);
		if (!filepath.exists()) {
			filepath.mkdirs();
		}
		File file = new File(fpn);
		if (!file.exists()) {
			try {
				file.createNewFile();
				Log.e(Thread.currentThread().getStackTrace()[2] + "", "createFile(" + fpn + ")");
			} catch (Exception e) {
				Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
			}
		}
		StringBuilder sb = new StringBuilder(time);
		sb.insert(4, "-");
		sb.insert(7, "-");
		sb.insert(10, " ");
		sb.insert(13, ":");
		sb.insert(16, ":");
		FileWriter fw;
		BufferedWriter bw;
		try {
			fw = new FileWriter(fpn, true);
			bw = new BufferedWriter(fw);
			String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gpx version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\"><metadata><starttime>"	+ sb + "</starttime><endtime>" + time + "</endtime><distance>0</distance><duration>00:00:00</duration><maxspeed>0</maxspeed></metadata><trk><trkseg></trkseg></trk></gpx>";
			bw.write(content);
			bw.flush();
			bw.close();
			fw.close();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
	}

	static void add(String filename, String time, String latitude, String longitude, String altitude, String speed, String distance, String duration) {
		String fp = Environment.getExternalStorageDirectory().getPath() + "/LocusMap/";
		String fpn = fp + filename;
		DocumentBuilderFactory DBF = DocumentBuilderFactory.newInstance();
		DocumentBuilder DB = null;
		try {
			DB = DBF.newDocumentBuilder();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		Document document = null;
		try {
			document = DB.parse(new FileInputStream(fpn));
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		document.getDocumentElement().getElementsByTagName("endtime").item(0).setTextContent(time);
		document.getDocumentElement().getElementsByTagName("distance").item(0).setTextContent(distance);
		document.getDocumentElement().getElementsByTagName("duration").item(0).setTextContent(duration);
		Element element_trkpt = document.createElement("trkpt");
		Attr attr = document.createAttribute("lat");
		attr.setValue(latitude);
		element_trkpt.setAttributeNode(attr);
		attr = document.createAttribute("lon");
		attr.setValue(longitude);
		element_trkpt.setAttributeNode(attr);
		Element element_time = document.createElement("time");
		element_time.setTextContent(time);
		element_trkpt.appendChild(element_time);
		Element element_ele = document.createElement("ele");	//Elevation (in meters)
		element_ele.setTextContent(altitude);
		element_trkpt.appendChild(element_ele);
		Element element_speed = document.createElement("speed");
		element_speed.setTextContent(speed);
		element_trkpt.appendChild(element_speed);
		document.getDocumentElement().getElementsByTagName("trkseg").item(0).appendChild(element_trkpt);
		TransformerFactory TF = TransformerFactory.newInstance();
		Transformer transformer = null;
		try {
			transformer = TF.newTransformer();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
		transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 换行
		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); // 缩进
		DOMSource DOMS = new DOMSource(document);
		StreamResult SR = new StreamResult(new File(fpn));
		try {
			transformer.transform(DOMS, SR);
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
	}

	static List<LatLng> read(String filepath) {
		Log.e(Thread.currentThread().getStackTrace()[2] + "", filepath);
		String filename = filepath.substring(filepath.lastIndexOf("/") + 1);
		String filebasename = filename.substring(0, filename.indexOf("."));
		Log.e(Thread.currentThread().getStackTrace()[2] + "", filebasename);
		String starttime = "", endtime = "", sdistance = "", sduration = "", speed="", info = "";
		double distance = 0;
		boolean isCalcDistance = false;
		MainApplication.msg = info;
		List<LatLng> points = new ArrayList<>();
		DocumentBuilderFactory DBF = DocumentBuilderFactory.newInstance();
		DocumentBuilder DB = null;
		try {
			DB = DBF.newDocumentBuilder();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		Document doc = null;
		try {
			doc = DB.parse(new FileInputStream(filepath));
		} catch (FileNotFoundException e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
			return null;
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		try {
			starttime = doc.getDocumentElement().getElementsByTagName("starttime").item(0).getFirstChild().getTextContent();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		try {
			endtime = doc.getDocumentElement().getElementsByTagName("endtime").item(0).getFirstChild().getTextContent();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		try {
			sdistance = doc.getDocumentElement().getElementsByTagName("distance").item(0).getFirstChild().getTextContent();
			distance = Double.parseDouble(sdistance);
			sdistance = sdistance.substring(0, sdistance.indexOf("."));
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
			isCalcDistance = true;
		}
		try {
			sduration = doc.getDocumentElement().getElementsByTagName("duration").item(0).getFirstChild().getTextContent();
			h = Integer.parseInt(sduration.substring(0, 2));
			m = Integer.parseInt(sduration.substring(3, 5));
			s = Integer.parseInt(sduration.substring(6));
			seconds = h * 3600 + m * 60 + s;
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		if (seconds != 0)
			speed = DF.format(distance / seconds);

		NodeList trkpt = doc.getDocumentElement().getElementsByTagName("trkpt");
		int trkpt_length = trkpt.getLength();
		if (trkpt_length > 0) {
			SDKInitializer.initialize(MainApplication.mContext);// SDK没有初始化，引用会崩溃
			for (int i = 0; i < trkpt_length; i++) {
				Element element = (Element) trkpt.item(i);
				LatLng point = new LatLng(Double.parseDouble(element.getAttribute("lat")), Double.parseDouble(element.getAttribute("lon")));
				//文件头无开始时间、结束时间、路程，智能计算
				if (starttime.equals("") && i == 0) {
					starttime = element.getElementsByTagName("time").item(0).getTextContent();
				}
				if (endtime.equals("") && i == trkpt_length - 1) {
					endtime = element.getElementsByTagName("time").item(0).getTextContent();
				}
				// https://blog.csdn.net/callmesen/article/details/40542949,GPS转BD
				CoordinateConverter converter = new CoordinateConverter();
				if (filebasename.endsWith("GCJ"))
					converter.from(CoordType.COMMON); //GCJ2BD
				else
					converter.from(CoordType.GPS); //WGS2BD
				converter.coord(point);
				point = converter.convert();
				points.add(point);
			}
			if (isCalcDistance) {
				distance = 0;
				for (int i=1; i<points.size(); i++) {
					distance += DistanceUtil.getDistance(points.get(i-1), points.get(i));
				}
				Date date1, date2;
				try {
					if (starttime.contains("T") && starttime.contains("Z") && endtime.contains("T") && endtime.contains("Z"))
						SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault());
					date1 = SDF.parse(starttime);
					date2 = SDF.parse(endtime);
					long duration = date2.getTime() - date1.getTime();
					seconds = (int)(duration / 1000);
					speed = DF.format(distance/seconds);
					sduration = SDF_HMS.format(seconds);
				} catch (Exception e) {
					Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
				}
				sdistance = distance + "";
				sdistance = sdistance.substring(0, sdistance.indexOf("."));
			}
			info = filename + "\n开始时间：" + starttime + "\n结束时间：" + endtime + "\n路程：" + sdistance + " 米\n时长：" + sduration + " (" + seconds + " 秒)\n平均速度：" + speed + "米/s\n" + trkpt_length + " 个点";
			MainApplication.msg = info;
			return points;
		} else {
			return null;
		}
	}

	static Track read1(String filepath) {
		Log.e(Thread.currentThread().getStackTrace()[2] + "", filepath);
		Track track = new Track();
		String filename = filepath.substring(filepath.lastIndexOf("/") + 1);
		String filebasename = filename.substring(0, filename.indexOf("."));
		Log.e(Thread.currentThread().getStackTrace()[2] + "", filebasename);
		//String starttime = "", endtime = "", sdistance = "", sduration = "", speed = "", info = "";
		double distance = 0;
		boolean isCalcDistance = false;
		//MainApplication.msg = info;
		List<LatLng> points = new ArrayList<>();
		DocumentBuilderFactory DBF = DocumentBuilderFactory.newInstance();
		DocumentBuilder DB = null;
		try {
			DB = DBF.newDocumentBuilder();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		Document doc = null;
		try {
			doc = DB.parse(new FileInputStream(filepath));
		} catch (FileNotFoundException e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
			return null;
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		try {
			track.starttime = doc.getDocumentElement().getElementsByTagName("starttime").item(0).getFirstChild().getTextContent();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		try {
			track.endtime = doc.getDocumentElement().getElementsByTagName("endtime").item(0).getFirstChild().getTextContent();
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		try {
			track.sdistance = doc.getDocumentElement().getElementsByTagName("distance").item(0).getFirstChild().getTextContent();
			distance = Double.parseDouble(track.sdistance);
			track.sdistance = track.sdistance.substring(0, track.sdistance.indexOf("."));
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
			isCalcDistance = true;
		}
		try {
			track.sduration = doc.getDocumentElement().getElementsByTagName("duration").item(0).getFirstChild().getTextContent();
			h = Integer.parseInt(track.sduration.substring(0, 2));
			m = Integer.parseInt(track.sduration.substring(3, 5));
			s = Integer.parseInt(track.sduration.substring(6));
			seconds = h * 3600 + m * 60 + s;
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		}
		if (seconds != 0)
			track.speed = DF.format(distance / seconds);

		NodeList trkpt = doc.getDocumentElement().getElementsByTagName("trkpt");
		int trkpt_length = trkpt.getLength();
		if (trkpt_length > 0) {
			SDKInitializer.initialize(MainApplication.mContext);// SDK没有初始化，引用会崩溃
			for (int i = 0; i < trkpt_length; i++) {
				Element element = (Element) trkpt.item(i);
				LatLng point = new LatLng(Double.parseDouble(element.getAttribute("lat")), Double.parseDouble(element.getAttribute("lon")));
				//文件头无开始时间、结束时间、路程，智能计算
				if (track.starttime.equals("") && i == 0) {
					track.starttime = element.getElementsByTagName("time").item(0).getTextContent();
				}
				if (track.endtime.equals("") && i == trkpt_length - 1) {
					track.endtime = element.getElementsByTagName("time").item(0).getTextContent();
				}
				// https://blog.csdn.net/callmesen/article/details/40542949,GPS转BD
				CoordinateConverter converter = new CoordinateConverter();
				if (filebasename.endsWith("GCJ"))
					converter.from(CoordType.COMMON); //GCJ2BD
				else
					converter.from(CoordType.GPS); //WGS2BD
				converter.coord(point);
				point = converter.convert();
				track.points.add(point);
			}
			if (isCalcDistance) {
				distance = 0;
				for (int i=1; i<points.size(); i++) {
					distance += DistanceUtil.getDistance(points.get(i-1), points.get(i));
				}
				Date date1, date2;
				try {
					if (track.starttime.contains("T") && track.starttime.contains("Z") && track.endtime.contains("T") && track.endtime.contains("Z"))
						SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault());
					date1 = SDF.parse(track.starttime);
					date2 = SDF.parse(track.endtime);
					long duration = date2.getTime() - date1.getTime();
					seconds = (int)(duration / 1000);
					track.speed = DF.format(distance/seconds);
					track.sduration = SDF_HMS.format(seconds);
				} catch (Exception e) {
					Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
				}
				track.sdistance = distance + "";
				track.sdistance = track.sdistance.substring(0, track.sdistance.indexOf("."));
			}
			track.info = filename + "\n开始时间：" + track.starttime + "\n结束时间：" + track.endtime + "\n路程：" + track.sdistance + " 米\n时长：" + track.sduration + " (" + seconds + " 秒)\n平均速度：" + track.speed + "米/s\n" + trkpt_length + " 个点";
			//MainApplication.msg = info;
			return track;
		} else {
			return null;
		}
	}

	static void append(String file, String content) {
		BufferedWriter BW = null;
		try {
			BW = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
			Date date = new Date();
			BW.write(SDF.format(date) + ": " + content + "\n");
		} catch (Exception e) {
			Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
		} finally {
			try {
				if (BW != null) {
					BW.close();
				}
			} catch (Exception e) {
				Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());
			}
		}
	}

}